// StreamManager.ts
import { ContentType, StreamEventHandlers } from '@/types';
import axios, { AxiosRequestConfig } from 'axios'

/**
 * 流式传输管理器
 * 功能：
 * 1. 处理分块数据接收
 * 2. 自动重连机制
 * 3. 心跳检测
 * 4. 背压管理
 * 5. Web Worker 集成
 */

export default class StreamManager {
    // 请求控制器（用于中断请求）
    private controller?: AbortController
    // 当前重试次数
    private retryCount = 0
    // 最大重试次数
    private readonly maxRetries = 3
    // 数据缓冲区（用于背压管理）
    private buffer: string[] = []
    // 暂停状态标识
    private isPaused = false
    // 心跳检测定时器
    private heartbeatInterval?: NodeJS.Timeout
    // 最后活动时间戳
    private lastActivity = Date.now()
    // Web Worker 实例
    private worker: Worker

    /**
     * 构造函数
     * @param apiUrl 接口地址
     * @param requestData 请求数据
     * @param handlers 事件处理器
     * @param headers 请求头
     */
    constructor(
        private readonly apiUrl: string,
        private readonly requestData: Record<string, any>,
        private readonly handlers: StreamEventHandlers,
        private readonly headers: any
    ) {
        const urlstr = new URL('./stream.worker.ts', import.meta.url)
        // 初始化 Web Worker
        this.worker = new Worker(urlstr, {
            type: 'module'  // 必须指定模块类型
        })
        // 设置 Worker 消息处理器
        this.worker.onmessage = this.handleWorkerMessage
    }

    /**
     * 启动流式连接
     */
    async connect() {
        try {
            // 创建新的 AbortController
            this.controller = new AbortController()
            // 开始流式传输
            await this.startStream()
            // 启动心跳检测
            //   this.startHeartbeat()
        } catch (error) {
            this.handleError(error)
        }
    }

    /**
     * 初始化流式请求
     */
    private async startStream() {
        // 发起 POST 请求
        const response = await axios.post(this.apiUrl, this.requestData, {
            headers: this.headers,
            responseType: 'stream', // 重要：声明流式响应类型
            signal: this.controller?.signal, // 绑定中断信号
            onDownloadProgress: (progress) => {
                // console.log(progress)
                // 更新最后活动时间
                this.lastActivity = Date.now()
                // 处理接收到的数据块
                this.processChunk(progress.event?.target?.responseText)
            }
        } as AxiosRequestConfig)
        console.log("response", response)

        // 设置流读取器
        // this.setupStreamReader(response.data.getReader())
    }

    /**
     * 设置流读取器
     * @param reader 可读流读取器
     */
    private setupStreamReader(reader: ReadableStreamDefaultReader) {
        const process = async () => {
            // 持续读取数据（除非处于暂停状态）
            while (!this.isPaused) {
                const { done, value } = await reader.read()
                if (done) {
                    // 流结束回调
                    this.handlers.onEnd()
                    return
                }
                // 将数据存入缓冲区
                this.buffer.push(value)
                // 检查背压情况
                this.checkBackpressure()
            }
        }
        process()
    }

    /**
     * 背压检查（防止客户端过载）
     */
    private checkBackpressure() {
        // 当缓冲区超过100个数据块时暂停接收
        if (this.buffer.length > 100000) {
            console.log("当缓冲区超过100个数据块时暂停接收")
            this.isPaused = true
            // 中断当前请求
            this.controller?.abort()
        }
    }

    /**
     * 处理数据块（使用 Web Worker）
     * @param chunk 原始数据块
     */
    private processChunk(chunk: string) {
        // 发送到 Web Worker 进行处理
        this.worker.postMessage({
            chunk,
            // type: this.detectContentType(chunk) // 自动检测内容类型
        })
    }

    /**
     * 处理 Worker 返回的消息
     */
    private handleWorkerMessage = (e: MessageEvent) => {
        const { type, content } = e.data
        if (type == 'DONE') {
            this.handlers.onEnd()
        } else if (type == 'sessionTitleData'){
            this.handlers.onTitleData(content)
        } else {
            // 将处理后的内容传递给上层
            this.handlers.onData(content)
            // 清空缓冲区
            this.buffer = []
        }


        // 如果之前处于暂停状态，尝试恢复连接
        // if (this.isPaused) {
        //     this.retryResume()
        // }
    }

    /**
     * 重试恢复连接（包含指数退避）
     */
    private async retryResume() {
        this.isPaused = false
        if (this.retryCount < this.maxRetries) {
            this.retryCount++
            // 指数退避延迟：1s, 2s, 4s...
            await new Promise(r =>
                setTimeout(r, 1000 * 2 ** this.retryCount))
            // 重新连接
            await this.connect()
        }
    }

    /**
     * 启动心跳检测
     */
    private startHeartbeat() {
        this.heartbeatInterval = setInterval(() => {
            // 15秒无活动触发心跳检测
            if (Date.now() - this.lastActivity > 15000) {
                this.sendHeartbeat()
            }
        }, 5000) // 每5秒检查一次
    }

    /**
     * 发送心跳请求
     */
    private sendHeartbeat() {
        axios.get(`${this.apiUrl}/heartbeat`, {
            signal: this.controller?.signal
        }).catch(() => {
            this.handleError(new Error('心跳检测失败'))
        })
    }

    /**
     * 错误处理
     * @param error 错误对象
     */
    private handleError(error: Error) {
        // 忽略主动取消的请求
        if (axios.isCancel(error)) return

        // 传递错误给上层处理器
        this.handlers.onError(error)
        // 尝试重新连接
        // this.retryResume()
    }

    /**
     * 断开连接（清理资源）
     */
    disconnect() {
        // 中断请求
        this.controller?.abort()
        // 清除心跳定时器
        clearInterval(this.heartbeatInterval)
        // 终止 Web Worker
        this.worker.terminate()
    }

    /**
     * 自动检测内容类型
     */
    private detectContentType(chunk: string): ContentType {
        // 简单的内容类型检测逻辑
        if (chunk.startsWith('```')) return 'code'
        if (/!\[.*?\]\(.*?\)/.test(chunk)) return 'image'
        return 'text'
    }
}



